from micropython import const
from machine import I2C

VEML6075_REG_CONF       = const(0x00)   # Configuration register (options below)
VEML6075_REG_UVA        = const(0x07)   # UVA register
VEML6075_REG_DUMMY      = const(0x08)   # Dark current register (NOT DUMMY)
VEML6075_REG_UVB        = const(0x09)   # UVB register
VEML6075_REG_UVCOMP1    = const(0x0A)   # Visible compensation register
VEML6075_REG_UVCOMP2    = const(0x0B)   # IR compensation register

VEML6075_UVI_UVA_VIS_COEFF = 2.22 # aka coeff "A"
VEML6075_UVI_UVA_IR_COEFF  = 1.33 # aka coeff "B"
VEML6075_UVI_UVB_VIS_COEFF = 2.95 # aka coeff "C"
VEML6075_UVI_UVB_IR_COEFF  = 1.74 # aka coeff "D"

VEML6075_UVI_UVA_RESPONSE = 0.001461
VEML6075_UVI_UVB_RESPONSE = 0.002591

class VEML6075:
    def __init__(self, i2c, addr=0x10):
		if i2c is None or i2c.__class__ != I2C:
			raise ValueError("I2C object needed as argument!")
		self._i2c = i2c
		self._addr = addr

    def measure(self):
        _config = bytes([(1 << 4) | (0 << 3) | (1 << 2) | (1 << 1), 0])  # IT:100ms; HD:0; UV+Trig: 1   AF=1 SD=0
        self._i2c.writeto_mem(self._addr, VEML6075_REG_CONF, _config)

    def getUV(self):
        uva = 0.0
        uvb = 0.0
        uvi = 0.0

        _data = self._i2c.readfrom_mem(self._addr, VEML6075_REG_UVA, 2)
        raw_uva = (_data[0] & 0x00FF) | ((_data[1] & 0x00FF) << 8)

        _data = self._i2c.readfrom_mem(self._addr, VEML6075_REG_DUMMY, 2)
        raw_dark = (_data[0] & 0x00FF) | ((_data[1] & 0x00FF) << 8)

        _data = self._i2c.readfrom_mem(self._addr, VEML6075_REG_UVB, 2)
        raw_uvb = (_data[0] & 0x00FF) | ((_data[1] & 0x00FF) << 8)

        _data = self._i2c.readfrom_mem(self._addr, VEML6075_REG_UVCOMP1, 2)
        raw_vis = (_data[0] & 0x00FF) | ((_data[1] & 0x00FF) << 8)

        _data = self._i2c.readfrom_mem(self._addr, VEML6075_REG_UVCOMP2, 2)
        raw_ir = (_data[0] & 0x00FF) | ((_data[1] & 0x00FF) << 8)

        # shutdown
        _config = bytes([(1 << 4) | (0 << 3) | (1 << 2) | (1 << 1) | 1, 0])
        self._i2c.writeto_mem(self._addr, VEML6075_REG_CONF, _config)

        comp_ir  = max(raw_ir - raw_dark, 0)
        comp_vis = max(raw_vis - raw_dark, 0)
        comp_uva = max(raw_uva - raw_dark, 0)
        comp_uvb = max(raw_uvb - raw_dark, 0)

        # Scale by coeffs from datasheet
        temp_vis = comp_vis * VEML6075_UVI_UVA_VIS_COEFF
        temp_ir  = comp_ir * VEML6075_UVI_UVA_IR_COEFF

        # Subtract out visible and IR components
        comp_uva = max(comp_uva - temp_ir, 0.0)
        comp_uva = max(comp_uva - temp_vis, 0.0)

        uva = comp_uva

        # Scale by coeffs from datasheet
        temp_vis = comp_vis * VEML6075_UVI_UVB_VIS_COEFF
        temp_ir  = comp_ir * VEML6075_UVI_UVB_IR_COEFF

        # Subtract out visible and IR components
        comp_uvb = max(comp_uvb - temp_ir, 0.0)
        comp_uvb = max(comp_uvb - temp_vis, 0.0)

        uvb = comp_uvb

        # 计算UV Index
        uva_weighted = comp_uva * VEML6075_UVI_UVA_RESPONSE
        uvb_weighted = comp_uvb * VEML6075_UVI_UVB_RESPONSE
        uvi = (uva_weighted + uvb_weighted) / 2.0

        return uva, uvb, uvi
